package cmd

import (
	"fmt"
	"gitee.com/lllgo/gopkg/files"
	"gitee.com/lllgo/opsctl/pkg/conf"
	"gitee.com/lllgo/opsctl/pkg/model"
	"gitee.com/lllgo/opsctl/pkg/tools"
	"github.com/spf13/cobra"
	"path/filepath"
	"strings"
	"testing"
)

func RegisterCmdPlugin(command string, f func(pc conf.PluginConfig, c conf.ComponentConfig) error, defPCs ...conf.PluginConfig) {
	var pluginsCfgs []conf.PluginConfig
	pluginConfig := conf.PluginPath
	_ = conf.BindConfig(pluginConfig, &pluginsCfgs, command)

	if len(defPCs) > 0 {
		pluginsCfgs = append(pluginsCfgs, defPCs...)
	}

	for _, cfg := range pluginsCfgs {
		if cfg.Dir != "" {
			cfg.Dir = files.Abs(pluginConfig, cfg.Dir)
		}

		tmp := &cobra.Command{
			Use:   cfg.Cmd,
			Short: cfg.Desc,
			Long:  cfg.Desc,
			RunE: func(command *cobra.Command, args []string) error {
				configs := conf.GetComponentConfig(cfg.Cmd)
				return tools.DispatchMultiConfig(configs, func(c conf.ComponentConfig) error {
					return f(cfg, c)
				})
			},
		}

		Register(nil, tmp)
	}

}

func GetHostsWithTag(cmdType conf.CommandType, tag string, names ...string) []tools.Host {
	return tools.GetHostsWithFunc(func(host tools.Host) {
		if tag != "" {
			if cmdType == conf.Add {
				_, _ = model.SaveTag(host.Name, host.IP(), tag)
			} else if cmdType == conf.Remove {
				_ = model.DeleteTag(host.Name, host.IP(), tag)
			}
		}
	}, names...)
}

type TestCmd struct {
	Name, Cmd, Cfg, ToolsDir string
	Want                     string
}

func TestExecute(t *testing.T, tests []TestCmd) {
	for _, tt := range tests {
		t.Run(tt.Name, func(t *testing.T) {
			if err := Execute(strings.Split(tt.Cmd, " ")); (tt.Want == "" && err != nil) || (err != nil && tt.Want != "" && !strings.Contains(err.Error(), tt.Want)) {
				fmt.Println(err)
				t.Errorf("cmd = %v, want %v", tt.Cmd, tt.Want)
			}
		})
	}
}

func TestInit(parentPath string) {
	testdataPath := parentPath + "../../testdata"
	conf.ConfigPath, _ = filepath.Abs(testdataPath + "/config")
	conf.InventoryPath, _ = filepath.Abs(testdataPath + "/hosts.ini")
	conf.PluginPath, _ = filepath.Abs(testdataPath + "/plugin.yaml")
}
